/*
 Funciona Perfectamente
 */
package funcionesDeSeleccion;

import elementosEvolutivos.Cromosoma;
import elementosEvolutivos.FuncSeleccion;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import util.Aleatorio;

public class CombateGladiadores implements FuncSeleccion {
	private double E;
    private double Z;
    public CombateGladiadores(double E, double Z){
        this.E=E;
        this.Z=Z;
    }
    public Collection<Cromosoma> seleccionar(Collection<Cromosoma> poblacion, int tam_sel) {
        /*
        ** Este metodo combina Torneo con Ranking
         * 
         * 1.Ordena los contricantes de mejores a peores
         *
         * 2.El proceso de eleccion de contrincantes sera a partir de un factor E y un factor Z.
         *   generaremos los numeros aleatorios a y b.   //una vez por combate
         *   generaremos los numeros aleatorios p1 y p2. //una vez por iteracion
         *   primer contrincante: iteramos de mejor a peor hasta que p1>E
         *   segundo contrincante: iteramos de mejor a peor hasta que p2 >E
         *   
         *   En caso de que algun numero aleatorio sea menor que Z, el contrincante se elejira aleatoriamente
         * 
         * 3.El enfrentamiento se decide generando un numero aleatorio. Se normalizaran los
         *  valores de los contrincantes como en ruleta y ganara aquel cuyo rango 0..M..1
         *  contenga a dicho numero.
         * 
         *  El vencedor pasara al conjunto de elegidos
         * 
         * 
         */
        Collection<Cromosoma> elegidos = new ArrayList<Cromosoma>();
        //double Z=0.8; //probabilidad de elegir contrincante en la iteracion i
        //double E=0.5; //probabilidad de elegir a ese contrincante aleatoriamente
        double a;     //aleatorio de primer contrincante  
        double b;     //aleatorio de segundo contrincante
        double p1;
        double p2;
        double p;
        int elejido1=0; //primer contrincante
        int elejido2=0; //segundo contrincante
        int vueltas=0;
        int ganador=0;
        boolean enc1; //tope1
        boolean enc2; //tope2
        int i;
                
                
        //Paso1. Ordenamos Poblacion
        Collections.sort((ArrayList<Cromosoma>)poblacion);
        //Paso2. Eleccion de contrincantes y Karate a Muerte
        while (vueltas<tam_sel){
        //por cada individuo a elejir iteramos este while    
            a=(double)Aleatorio.getDoubleAleatorio();
            b=(double)Aleatorio.getDoubleAleatorio();
            p1=(double)Aleatorio.getDoubleAleatorio();
            p2=(double)Aleatorio.getDoubleAleatorio();
            enc1=false;
            enc2=false;
            i=0;
            //caso de a o b menores
            if(a>Z){
                elejido1 = (int) Math.floor(p1 * (poblacion.size()));
                enc1=true;

            }
            if(b>Z){
                elejido2 = (int) Math.floor(p2 * (poblacion.size()));
                enc1=true;
                
            }
            //En el caso de tener que iterar
            while((enc1==false)||(enc2==false)){
                    p1=(double)Aleatorio.getDoubleAleatorio(); 
                    p2=(double)Aleatorio.getDoubleAleatorio(); 
                if((enc1==false) && (p1>E)){
                    elejido1=i;
                    enc1=true;
                }
            
                if((enc2==false) && (p2>E)){
                    elejido2=i;
                    enc2=true;
                }
               i++;
            }//while
            /*
             * Combate!!!
             *
             */
            System.out.println(elejido1 + " vs "+elejido2);
            double sumaaux =  ((ArrayList<Cromosoma>)poblacion).get(elejido1).getAptitud() + ((ArrayList<Cromosoma>)poblacion).get(elejido2).getAptitud(); 
            p1 = (((ArrayList<Cromosoma>)poblacion).get(elejido1).getAptitud())/(sumaaux);
            p2 = (((ArrayList<Cromosoma>)poblacion).get(elejido2).getAptitud())/(sumaaux);
            p=(double)Aleatorio.getDoubleAleatorio();
            
            if(p<p1){ganador=elejido1;} else {ganador=elejido2;}
            
            elegidos.add(((ArrayList<Cromosoma>)poblacion).get(ganador).clone());
            vueltas++;
        }//while
        
        return elegidos;
    }//seleccionar
    
}
